package com.zenithmind.mall.controller;

import com.zenithmind.common.annotation.Log;
import com.zenithmind.common.annotation.RequireAuth;
import com.zenithmind.common.constant.OperationTypeEnum;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.mall.pojo.dto.ProductDTO;
import com.zenithmind.mall.pojo.dto.StatusUpdateRequest;
import com.zenithmind.mall.pojo.query.ProductQuery;
import com.zenithmind.mall.pojo.vo.ProductVO;
import com.zenithmind.mall.service.ProductManagementService;
import com.zenithmind.mall.service.ProductQueryService;
import com.zenithmind.mall.service.ProductStockService;
import com.zenithmind.mall.service.ProductStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;

/**
 * 商品控制器 - 遵循控制器层最佳实践，只处理HTTP请求响应，业务逻辑委托给服务层
 *
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/mall/product")
@RequiredArgsConstructor
@Tag(name = "商品管理", description = "商品相关接口")
@Validated
public class ProductController {

    private final ProductManagementService productManagementService;
    private final ProductQueryService productQueryService;
    private final ProductStockService productStockService;
    private final ProductStatisticsService productStatisticsService;

    @GetMapping("/page")
    @Operation(summary = "分页查询商品列表", description = "支持多条件查询和排序")
    public Result<PageResult<ProductVO>> getProductPage(@Validated ProductQuery query) {
        log.info("分页查询商品列表: {}", query);
        PageResult<ProductVO> result = productQueryService.getProductPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询商品详情", description = "根据商品ID查询详细信息")
    @Parameter(name = "id", description = "商品ID", required = true)
    public Result<ProductVO> getProductById(@PathVariable @NotBlank String id) {
        log.info("查询商品详情: {}", id);
        ProductVO result = productQueryService.getProductById(id);
        return Result.success(result);
    }

    @PostMapping
    @Operation(summary = "创建商品", description = "创建新商品")
    @RequireAuth(admin = true)
    @Log(description = "创建商品", operationType = OperationTypeEnum.ADD)
    public Result<String> createProduct(@Validated @RequestBody ProductDTO productDTO) {
        log.info("创建商品: {}", productDTO.getName());
        String productId = productManagementService.createProduct(productDTO);
        return Result.success(productId);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新商品", description = "更新商品信息")
    @Parameter(name = "id", description = "商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "更新商品", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> updateProduct(@PathVariable @NotBlank String id,
                                       @Validated @RequestBody ProductDTO productDTO) {
        log.info("更新商品: {}", id);
        Boolean result = productManagementService.updateProduct(id, productDTO);
        return Result.success(result);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除商品", description = "删除指定商品")
    @Parameter(name = "id", description = "商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "删除商品", operationType = OperationTypeEnum.DELETE)
    public Result<Boolean> deleteProduct(@PathVariable @NotBlank String id) {
        log.info("删除商品: {}", id);
        Boolean result = productManagementService.deleteProduct(id);
        return Result.success(result);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除商品", description = "批量删除多个商品")
    @RequireAuth(admin = true)
    @Log(description = "批量删除商品", operationType = OperationTypeEnum.DELETE)
    public Result<Boolean> deleteProducts(@RequestBody @NotEmpty List<String> ids) {
        log.info("批量删除商品: {}", ids);
        Boolean result = productManagementService.deleteProducts(ids);
        return Result.success(result);
    }

    @PutMapping("/{id}/on-shelf")
    @Operation(summary = "上架商品", description = "将商品设置为上架状态")
    @Parameter(name = "id", description = "商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "上架商品", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> onShelf(@PathVariable @NotBlank String id) {
        log.info("上架商品: {}", id);
        Boolean result = productManagementService.onShelf(id);
        return Result.success(result);
    }

    @PutMapping("/{id}/off-shelf")
    @Operation(summary = "下架商品", description = "将商品设置为下架状态")
    @Parameter(name = "id", description = "商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "下架商品", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> offShelf(@PathVariable @NotBlank String id) {
        log.info("下架商品: {}", id);
        Boolean result = productManagementService.offShelf(id);
        return Result.success(result);
    }

    @PutMapping("/{id}/status")
    @Operation(summary = "更新商品状态", description = "更新指定商品的状态")
    @Parameter(name = "id", description = "商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "更新商品状态", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> updateProductStatus(@PathVariable @NotBlank String id,
                                             @Validated @RequestBody StatusUpdateRequest request) {
        log.info("更新商品状态: {} -> {}", id, request.getStatus());
        Boolean result = productManagementService.updateProductStatus(id, request.getStatus());
        return Result.success(result);
    }

    @GetMapping("/recommend")
    @Operation(summary = "查询推荐商品", description = "获取推荐商品列表")
    @Parameter(name = "limit", description = "限制数量", required = false)
    public Result<List<ProductVO>> getRecommendProducts(@RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("查询推荐商品，限制数量: {}", limit);
        List<ProductVO> result = productQueryService.getRecommendProducts(limit);
        return Result.success(result);
    }

    @GetMapping("/hot")
    @Operation(summary = "查询热销商品", description = "获取热销商品列表")
    @Parameter(name = "limit", description = "限制数量", required = false)
    public Result<List<ProductVO>> getHotProducts(@RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("查询热销商品，限制数量: {}", limit);
        List<ProductVO> result = productQueryService.getHotProducts(limit);
        return Result.success(result);
    }

    @GetMapping("/new")
    @Operation(summary = "查询新品", description = "获取新品列表")
    @Parameter(name = "limit", description = "限制数量", required = false)
    public Result<List<ProductVO>> getNewProducts(@RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("查询新品，限制数量: {}", limit);
        List<ProductVO> result = productQueryService.getNewProducts(limit);
        return Result.success(result);
    }

    @PostMapping("/{id}/view")
    @Operation(summary = "增加商品浏览量", description = "记录商品浏览")
    @Parameter(name = "id", description = "商品ID", required = true)
    public Result<Void> increaseViewCount(@PathVariable @NotBlank String id) {
        log.info("增加商品浏览量: {}", id);
        productStatisticsService.increaseViewCount(id);
        return Result.success();
    }

    @GetMapping("/{id}/stock")
    @Operation(summary = "检查商品库存", description = "检查指定数量的库存是否充足")
    @Parameter(name = "id", description = "商品ID", required = true)
    @Parameter(name = "quantity", description = "需要的数量", required = true)
    public Result<Boolean> checkStock(@PathVariable @NotBlank String id,
                                    @RequestParam @Min(1) Integer quantity) {
        log.info("检查商品库存: {} 数量: {}", id, quantity);
        Boolean result = productStockService.checkStock(id, quantity);
        return Result.success(result);
    }

    @GetMapping("/{id}/stock/current")
    @Operation(summary = "获取当前库存", description = "获取商品当前库存数量")
    @Parameter(name = "id", description = "商品ID", required = true)
    public Result<Integer> getCurrentStock(@PathVariable @NotBlank String id) {
        log.info("获取当前库存: {}", id);
        Integer result = productStockService.getCurrentStock(id);
        return Result.success(result);
    }

    @GetMapping("/{id}/statistics")
    @Operation(summary = "获取商品统计", description = "获取商品统计信息")
    @Parameter(name = "id", description = "商品ID", required = true)
    public Result<Object> getStatistics(@PathVariable @NotBlank String id) {
        log.info("获取商品统计: {}", id);
        Object result = productStatisticsService.getStatisticsReport(id);
        return Result.success(result);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索商品", description = "根据关键词搜索商品")
    @Parameter(name = "keyword", description = "搜索关键词", required = true)
    @Parameter(name = "pageNum", description = "页码", required = false)
    @Parameter(name = "pageSize", description = "页大小", required = false)
    public Result<PageResult<ProductVO>> searchProducts(@RequestParam @NotBlank String keyword,
                                                       @RequestParam(defaultValue = "1") @Min(1) Integer pageNum,
                                                       @RequestParam(defaultValue = "10") @Min(1) Integer pageSize) {
        log.info("搜索商品: {} 页码: {} 页大小: {}", keyword, pageNum, pageSize);
        PageResult<ProductVO> result = productQueryService.searchProducts(keyword, pageNum, pageSize);
        return Result.success(result);
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "根据分类查询商品", description = "获取指定分类的商品列表")
    @Parameter(name = "categoryId", description = "分类ID", required = true)
    @Parameter(name = "limit", description = "限制数量", required = false)
    public Result<List<ProductVO>> getProductsByCategory(@PathVariable @NotBlank String categoryId,
                                                        @RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("根据分类查询商品: {} 限制数量: {}", categoryId, limit);
        List<ProductVO> result = productQueryService.getProductsByCategory(categoryId, limit);
        return Result.success(result);
    }

    @GetMapping("/{id}/related")
    @Operation(summary = "获取相关商品", description = "获取与指定商品相关的商品列表")
    @Parameter(name = "id", description = "商品ID", required = true)
    @Parameter(name = "limit", description = "限制数量", required = false)
    public Result<List<ProductVO>> getRelatedProducts(@PathVariable @NotBlank String id,
                                                     @RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("获取相关商品: {} 限制数量: {}", id, limit);
        List<ProductVO> result = productQueryService.getRelatedProducts(id, limit);
        return Result.success(result);
    }

    @PostMapping("/{id}/copy")
    @Operation(summary = "复制商品", description = "复制现有商品创建新商品")
    @Parameter(name = "id", description = "原商品ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "复制商品", operationType = OperationTypeEnum.ADD)
    public Result<String> copyProduct(@PathVariable @NotBlank String id) {
        log.info("复制商品: {}", id);
        String result = productManagementService.copyProduct(id);
        return Result.success(result);
    }

    @PutMapping("/batch/on-shelf")
    @Operation(summary = "批量上架商品", description = "批量将商品设置为上架状态")
    @RequireAuth(admin = true)
    @Log(description = "批量上架商品", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> batchOnShelf(@RequestBody @NotEmpty List<String> ids) {
        log.info("批量上架商品: {}", ids);
        Boolean result = productManagementService.batchOnShelf(ids);
        return Result.success(result);
    }

    @PutMapping("/batch/off-shelf")
    @Operation(summary = "批量下架商品", description = "批量将商品设置为下架状态")
    @RequireAuth(admin = true)
    @Log(description = "批量下架商品", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> batchOffShelf(@RequestBody @NotEmpty List<String> ids) {
        log.info("批量下架商品: {}", ids);
        Boolean result = productManagementService.batchOffShelf(ids);
        return Result.success(result);
    }
}
